﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Emil.GMP;
using ZedGraph;
using System.Threading;

namespace BYU_ECC {
	public partial class Form1 : Form 
    {
		public Form1() 
        {
			InitializeComponent();
		}

        private void Form1_Load(object sender, EventArgs e)
        {
            CreateChart(zgc1);
        }

        public void CreateChart(ZedGraphControl zgc)
        {
            GraphPane myPane = zgc.GraphPane;

            // Set the titles
            myPane.Title.Text = "ECC Point Demo";
            myPane.XAxis.Title.Text = "X";
            myPane.YAxis.Title.Text = "Y";

            // Get a random number generator
            Random rand = new Random();

            // Populate a PointPairList with a log-based function and some random variability
            PointPairList list = new PointPairList();

            // Add the curve
            LineItem myCurve = myPane.AddCurve("Points", list, Color.Black, SymbolType.Diamond);
            // Don't display the line (This makes a scatter plot)
            myCurve.Line.IsVisible = false;
            // Hide the symbol outline
            myCurve.Symbol.Border.IsVisible = false;
            // Fill the symbol interior with color
            myCurve.Symbol.Fill = new Fill(Color.Firebrick);

            // Fill the background of the chart rect and pane
            myPane.Chart.Fill = new Fill(Color.White, Color.LightGoldenrodYellow, 45.0f);
            myPane.Fill = new Fill(Color.White, Color.SlateGray, 45.0f);

            zgc.AxisChange();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (timer1.Enabled)
            {
                timer1.Stop();
                button1.Text = "Start";
            }
            else
            {
                button1.Text = "Stop";
                timer1.Start();
            }
            
        }


        void pptexample()
        {
            Curve.GenerateCurve(new BigInt("1"), new BigInt("1"), new BigInt("23"));

            Point P = Curve.MakePoint(new BigInt("1"), new BigInt("7"));
            //Print out initial point
            appendValidPoint(P);

            Point Q = Curve.MakePoint(new BigInt("17"),new BigInt("3"));

            appendValidPoint(Q);

            Point R = P + Q;
            appendValidPoint(R);
            
    

            Point kP = P;
            for (int k = 2; k <= 20; k++)
            {
                kP = k * P;
                label1.Text += k + " * " + P.ToString() + " = ";
                appendValidPoint(kP);
            }
            
        }

		void bookexample() {
			Curve.GenerateCurve(new BigInt("1"), new BigInt("1"), new BigInt("23"));

			Point P = Curve.MakePoint(new BigInt("3"), new BigInt("10"));
			//Print out initial point
			appendValidPoint(P);

			Point Q = Curve.MakePoint(new BigInt("9"), new BigInt("7"));

			appendValidPoint(Q);

			Point R = P + Q;
			appendValidPoint(R);



			Point kP = P;
			for (int k = 2; k <= 20; k++) {
				kP = k * P;
				label1.Text += k + " * " + P.ToString() + " = ";
				appendValidPoint(kP);
			}

		}
		/*
        void pptexample2()
        {
            Curve.GenerateCurve(1, 2, 11);

            Point P = Curve.MakePoint(9, 5);

            //Print out initial point
            appendValidPoint(P);

            Point Q = P + P;
            appendValidPoint(Q);

		}

		void siteexample() {
			Curve.GenerateCurve(1, 0, 23);

			Point P = Curve.MakePoint(9, 5);

			//Print out initial point
			appendValidPoint(P);

			Point Q = P + P;
			appendValidPoint(Q);

		}
		*/

        void appendValidPoint(Point p)
        {
			Console.Write(p.ToString() + ": ");
            label1.Text += p.ToString() + ": ";
            if (Curve.IsValidPoint(p))
            {
                label1.Text += String.Format("valid");
				Console.WriteLine("valid");
            }
            else
            {
				label1.Text += String.Format("invalid");
				Console.WriteLine("invalid");
            }
            label1.Text += "\r\n";
        }


        int k = 1;
        void pdfexample(IPointListEdit list)
        {
            Curve.GenerateCurve(new BigInt(textBoxA.Text), new BigInt(textBoxB.Text), new BigInt(textBoxP.Text));
            Point P = Curve.MakePoint(new BigInt(textBoxX.Text), new BigInt(textBoxY.Text));

            Point kP = k * P;
            k++;
            appendValidPoint(kP);

            if (kP != Point.Infinity)
            {
                list.Add((int)kP.x, (int)kP.y);
            }
            else
            {
                k = 1;
                timer1.Stop();
                button1.Text = "Start";
            }
            
        }

		void encryptionexample(IPointListEdit list) {
			Point P = ParameterGenerator.BasePoint;

			Point kP = k * P;
			k++;
			appendValidPoint(kP);

			if (kP != Point.Infinity) {
				list.Add((int)kP.x, (int)kP.y);
			} else {
				k = 1;
				timer1.Stop();
			}
		}

        private void timer1_Tick(object sender, EventArgs e)
        {
            // Make sure that the curvelist has at least one curve
            if (zgc1.GraphPane.CurveList.Count <= 0)
                return;

            // Get the first CurveItem in the graph
            LineItem curve = zgc1.GraphPane.CurveList[0] as LineItem;
            if (curve == null)
                return;

            // Get the PointPairList
            IPointListEdit list = curve.Points as IPointListEdit;
            // If this is null, it means the reference at curve.Points does not
            // support IPointListEdit, so we won't be able to modify it
            if (list == null)
                return;

            pdfexample(list);

            // Make sure the Y axis is rescaled to accommodate actual data
            zgc1.AxisChange();
            // Force a redraw
            zgc1.Invalidate();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Curve.GenerateCurve(new BigInt(textBoxA.Text), new BigInt(textBoxB.Text), new BigInt(textBoxP.Text));
            if (Curve.IsValidPoint(new Point(new BigInt(textBoxX.Text), new BigInt(textBoxY.Text))))
                label1.Text = "Valid point";
            else 
                label1.Text = "Invalid point";
        }

        private void button4_Click(object sender, EventArgs e)
        {
                   
            // Make sure that the curvelist has at least one curve
            if (zgc1.GraphPane.CurveList.Count <= 0)
                return;

            // Get the first CurveItem in the graph
            LineItem curve = zgc1.GraphPane.CurveList[0] as LineItem;
            if (curve == null)
                return;

            // Get the PointPairList
            IPointListEdit list = curve.Points as IPointListEdit;
            // If this is null, it means the reference at curve.Points does not
            // support IPointListEdit, so we won't be able to modify it
            if (list == null)
                return;

            list.Clear();

            // Make sure the Y axis is rescaled to accommodate actual data
            zgc1.AxisChange();
            // Force a redraw
            zgc1.Invalidate();

            k = 1;
            label1.Text = "";
        }


	}
}
